package cn.edu.sgu.www.pms.util;

import org.springframework.web.multipart.MultipartFile;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**
 * String工具类
 * @author 沐雨橙风ιε
 * @version 1.0
 */
public class StringUtils {

    /**
     * 判断字符串是否为null或""
     * 字符串为""或null返回true，否则返回false
     * @param str 要判断的字符串
     * @return boolean
     */
    public static boolean isEmpty(String str) {
        return isNullOrEmpty(str);
    }

    /**
     * 判断字符串是否为""或null
     * 字符串为""或null返回false，否则返回true
     * @param str 要判断的字符串
     * @return boolean
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    /**
     * 判断字符串是否为空白字符
     * 字符串为空白字符返回true，否则返回false
     * @param str 要判断的字符串
     * @return boolean
     */
    public static boolean isBlank(String str) {
        return str.trim().length() == 0;
    }

    /**
     * 判断字符串是不是空白字符
     * 字符串不是空白字符返回true，否则返回false
     * @param str 要判断的字符串
     * @return boolean
     */
    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    /**
     * 判断字符串是否为null或""
     * 字符串为""或null返回true，否则返回false
     * @param str 要判断的字符串
     * @return boolean
     */
    public static boolean isNullOrEmpty(String str) {
        return str == null || str.isEmpty() || !isNotBlank(str);
    }

    /**
     * 检查字符串是否包含空白字符
     * 如果不包含空格返回true，否则返回false
     * @param str 需要比较的字符串
     * @return boolean
     */
    public static boolean containsSpace(String str) {
        // 去除空白字符后字符串的长度
        int realLength = str.replaceAll("\\s", "").length();
        // 字符串原来的长度
        int originalLength = str.length();

        return realLength == originalLength;
    }

    /**
     * 根据当前时间生成UUID
     * @return String
     */
    public static String uuid() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        LocalDateTime localDate = LocalDateTime.now();

        return localDate.format(formatter);
    }

    /**
     * 将日期时间转为字符串
     * @return String
     */
    public static String toTimeString(LocalDateTime localDateTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        return localDateTime.format(formatter);
    }

    /**
     * 将日期转为字符串
     * @return String
     */
    public static String toTimeString(LocalDate localDate) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        return localDate.format(formatter);
    }

    /**
     * 将时间转为字符串
     * @return String
     */
    public static String toTimeString(LocalTime time) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");

        return time.format(formatter);
    }

    /**
     * 通过文件名获取文件类型
     * @param fileName 文件名
     */
    public static String getFileType(String fileName) {
        // 得到文件名中最后一次出现"."的位置
        int index = fileName.lastIndexOf('.');

        // 文件类型统一转换为小写
        return fileName.substring(index).toLowerCase();
    }

    /**
     * 获取文件名
     * @param filename String
     * @return String 由当前时间生成的新文件名
     */
    public static String getFileName(String filename) {
        // 返回uuid.文件类型，如：20220618131456.jpg
        return uuid() + getFileType(filename);
    }

    /**
     * 获取文件名
     * @param file MultipartFile对象
     * @return String 由当前时间生成的新文件名
     */
    public static String getFileName(MultipartFile file) {
        // 得到上传文件的原始文件名
        String filename = file.getOriginalFilename();

        // 判断文件名是否为空
        if (isNullOrEmpty(filename)) {
            throw new RuntimeException("获取文件名失败！");
        }

        // 返回uuid.文件类型，如：20220618131456.jpg
        return getFileName(filename);
    }

    /**
     * 驼峰命名转下划线命名
     * @param str 待转换的字符串
     * @return String
     */
    public static String toLower(String str) {
        // 小写和大写紧挨一起的地方加上分隔符_，然后全部转为小写
        str = str.replaceAll("([a-z])([A-Z])", "$1_$2");

        return str.toLowerCase();
    }

    /**
     * 下划线命名转驼峰命名
     * @param str 待转换的字符串
     * @return String
     */
    public static String toUpper(String str) {
        // 字符串包含下划线_
        if(str.contains("_")) {
            // 将字符串根据_分割成数组
            String[] array = str.split("_");

            StringBuilder sb = new StringBuilder();

            // 首单词直接拼接
            sb.append(array[0]);

            // 从第二个单词开始，将每个单词首字母转为大写
            for (int i = 1; i < array.length; i++) {
                String s = array[i];
                String letter = s.substring(0, 1).toUpperCase() + s.substring(1);

                sb.append(letter);
            }

            return sb.toString();
        }

        return str;
    }

    /**
     * 加密：解决下载时文件名中文乱码的问题
     * @param fileName 待加密文件名
     * @return String 加密后的文件名
     * @throws UnsupportedEncodingException URLEncoder.encode()方法抛出的异常
     */
    public static String encode(String fileName) throws UnsupportedEncodingException {
        return URLEncoder.encode(fileName, "utf-8");
    }

}